/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2015-07-29     Arda.Fu      first implementation
 */
#include <stdint.h>
#include <rtthread.h>
#include <rtdevice.h>

#include <n32g45x_gpio.h>

/* defined the LED1 pin: PA8 */
#define LED1_PIN    67
/* defined the LED2 pin: PB4 */
#define LED2_PIN    67
/* defined the LED3 pin: PB5 */
#define LED3_PIN    67

void user_epd_task_init(void);
int main(void)
{
    uint32_t Speed = 200;
    /* Remap JTAG_NRST(PB4) */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
    GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_SW_ENABLE, ENABLE); //ONLY SW mode
    /* set LED1 pin mode to output */
    rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LED3_PIN, PIN_MODE_OUTPUT);
    rt_pin_write(LED1_PIN, PIN_LOW);
    rt_pin_write(LED2_PIN, PIN_LOW);
    rt_pin_write(LED3_PIN, PIN_LOW);

    user_epd_task_init();

    while (1)
    {
//        rt_pin_write(LED1_PIN, PIN_LOW);
//        rt_thread_mdelay(Speed);
//        rt_pin_write(LED1_PIN, PIN_HIGH);
        rt_thread_mdelay(Speed);
    }
}

//====================================================================//
rt_event_t rt_event_find(const char *name)
{
    struct rt_object_information *information;
    information = rt_object_get_information(RT_Object_Class_Event);
    RT_ASSERT(information != RT_NULL);
    rt_list_t *list = &information->object_list;
    for(rt_list_t *node = list->next; node != list; node = node->next) {
        struct rt_object *obj = rt_container_of(node, struct rt_object, list);
        struct rt_event *e = (struct rt_event *)obj;
        if(rt_strcmp(name, e->parent.parent.name) == 0) {
            return e;
        }
    }
    
    return RT_NULL;
}
#include <rthw.h>
void event_info_print(rt_event_t evt)
{
    rt_uint8_t type;
    rt_uint8_t flag;
    uint32_t set;
    rt_base_t temp = rt_hw_interrupt_disable();
    type = evt->parent.parent.type;
    flag = evt->parent.parent.flag;
    set = evt->set;
    rt_hw_interrupt_enable(temp);
    rt_kprintf("name: %s, type index:%d, flag:%08x, set:%08x\r\n", evt->parent.parent.name, type, flag, set);
    rt_list_t *list = &evt->parent.suspend_thread;
    rt_kprintf("suspend thread:\r\n");
    for(rt_list_t *node = list->next; node != list; node = node->next) {
        struct rt_thread *thread = rt_container_of(node, struct rt_thread, tlist);
        rt_kprintf("name:%s, priority:%d/%d(cur/init), stack:%d@%p:%p\r\n", thread->name
            , thread->current_priority, thread->init_priority
            , thread->stack_size, thread->stack_addr, thread->sp);
    }
}

int event_find_test(int argc, char *argv[])
{
    if(argc == 1) {
        rt_kprintf("event_find <name>\r\n");
        return 0;
    }
    const char *name = argv[1];
    rt_event_t evt = rt_event_find(name);
    if(evt == RT_NULL) {
        rt_kprintf("%s not found\r\n", name);
    } else {
        event_info_print(evt);
    }
    return 0;
}
MSH_CMD_EXPORT_ALIAS(event_find_test, event_find, test for event_find.);

#define CTOHEX(c)       (((c)>='0'&&(c)<='9')?(c)-'0':((c)>='a'&&(c)<='f')?(c)-'a'+10:((c)>='A' && (c)<='F')?(c)-'A'+10:0)
uint32_t atohex(const char *str)
{
    uint32_t ret = 0;
    const char *str_p;
    if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
        str_p = &str[2];
    } else {
        str_p = str;
    }
    for(int i=0; (i<8) && str_p[i]; i++) {
        ret <<= 4;
        ret += CTOHEX(str_p[i]);
    }
    return ret;
}
static void mem_usage(void)
{
    rt_kprintf("Usage: mem <cmd> [param]\r\n");
    rt_kprintf("\tread <addr> [size]                - read mem\r\n");
    //rt_kprintf("\twrite <addr> <data0> [data1...]   - write mem\r\n");
}
int mem_test(int argc, char *argv[])
{
    if(argc == 1) {
        mem_usage();
        return 0;
    }
    if(rt_strcmp(argv[1], "read") == 0) {
        uint32_t addr = atohex(argv[2]);
        uint32_t size = atohex(argv[3]);
        rt_kprintf("mem read %d@0x%08x\r\n", size, addr);
        rt_kprintf("         00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
        for(uint32_t i=0; i<size; i++) {
            if((i&0xF) == 0x0) {
                rt_kprintf("\r\n%08x:", addr + i);
            }
            rt_kprintf("%02x ", ((uint8_t *)addr)[i]);
        }
        rt_kprintf("\r\n");
    } /*else if(rt_strcmp(argv[2], "write") == 0) {
        uint32_t addr = atohex(argv[3]);
        uint32_t data;
        int y0 = atoi(argv[5]);
        int x1 = atoi(argv[6]);
        int y1 = atoi(argv[7]);
        rt_kprintf("paint line %d,%d,%d,%d,%d\r\n", colored, x0, y0, x1, y1);
        epd_paint_draw_line(&paint, x0, y0, x1, y1, colored);
    } */else {
        mem_usage();
        return -1;
    }

    return 0;
}

MSH_CMD_EXPORT_ALIAS(mem_test, mem, test for mem read write.);
